﻿using DotNet.Data;
using DotNet.Helper;
using DotNet.Utility;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using XNWebModel;

namespace XNWebService
{
    public class UserService
    {
        private readonly Repository<UserModel> dao = new Repository<UserModel>(new SiteDatabase());

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="model">用户模型</param>
        public BoolMessage Register(UserModel model)
        {
            model.Account = model.Account.Trim();
            var result = EntityHelper.ValidAsMessage(model);
            if (result.Failure)
            {
                return result;
            }

            var resultx = ExistsAccount(model.Account);
            if (resultx.Failure)
            {
                return resultx;
            }

            model.Id = StringHelper.Guid();
            model.Password = GenerateEncryptPassword(model.Password);
            model.IsLogin = false;

            try
            {
                dao.Insert(model);
                return BoolMessage.True;
            }
            catch (Exception ex)
            {
                return new BoolMessage(false, ex.Message);
            }
        }

        /// <summary>
        /// 判断指定的账号是否已经存在
        /// </summary>
        /// <param name="account">账号</param>
        public BoolMessage ExistsAccount(string account)
        {
            var v_result = ValidateAccount(account);
            if (v_result.Failure)
            {
                return v_result;
            }
            account = account.Trim();
            var has = dao.Exists(p => p.Account == account);
            return has ? new BoolMessage(false, "指定的手机号码已经存在") : BoolMessage.True;
        }

        public BoolMessage ModifyPassword(string account, string oldPassword, string newPassword)
        {
            var v_result = ValidateAccount(account);
            if (v_result.Failure)
            {
                return v_result;
            }
            if (string.IsNullOrEmpty(oldPassword))
            {
                return new BoolMessage(false, "请输入旧密码");
            }
            if (string.IsNullOrEmpty(newPassword))
            {
                return new BoolMessage(false, "请输入新密码");
            }

            account = account.Trim();

            var model = dao.Get(p => p.Account == account);
            if (model == null)
            {
                return new BoolMessage(false, "无效的手机号码");
            }
            if (!model.Password.Equals(GenerateEncryptPassword(oldPassword)))
            {
                return new BoolMessage(false, "输入的原密码不正确");
            }

            return ResetPassword(account, newPassword);
        }

        public BoolMessage ResetPassword(string account, string newPassword)
        {
            var vc_result = ValidateAccount(account);
            if (vc_result.Failure)
            {
                return vc_result;
            }
            if (string.IsNullOrEmpty(newPassword))
            {
                return new BoolMessage(false, "请输入新密码");
            }

            account = account.Trim();
            var result = ExistsAccount(account);
            if (result.Success)
            {
                return new BoolMessage(false, "无效的手机号码");
            }

            var model = new UserModel();
            model.Password = newPassword;
            //检测密码长度

            var v_result = ValidateProperty(model, nameof(UserModel.Password), model.Password);
            if (v_result.Failure)
            {
                return v_result;
            }

            model.Password = GenerateEncryptPassword(newPassword);
            dao.Update(model, p => p.Account == account, new[] { nameof(UserModel.Password) });
            return BoolMessage.True;
        }

        public BoolMessage Login(string account, string password)
        {
            var v_result = ValidateAccount(account);
            if (v_result.Failure)
            {
                return v_result;
            }
            if (string.IsNullOrEmpty(password))
            {
                return new BoolMessage(false, "请输入密码");
            }

            account = account.Trim();
            var model = dao.Get(p => p.Account == account);
            if (model == null)
            {
                return new BoolMessage(false, "账号密码错误");
            }

            var encryptedPwd = GenerateEncryptPassword(password);
            if (!model.Password.Equals(encryptedPwd))
            {
                return new BoolMessage(false, "账号密码错误");
            }

            model.IsLogin = true;
            dao.Update(model, p => p.Account == account, new[] { nameof(UserModel.IsLogin) });
            return BoolMessage.True;
        }

        /// <summary>
        /// 密文登陆
        /// </summary>
        /// <param name="account">帐号</param>
        /// <param name="encryptpassword">密文密码</param>
        /// <returns></returns>
        public BoolMessage LoginWithEncrypt(string account, string encryptpassword)
        {
            var v_result = ValidateAccount(account);
            if (v_result.Failure)
            {
                return v_result;
            }
            if (string.IsNullOrEmpty(encryptpassword))
            {
                return new BoolMessage(false, "请输入密码");
            }

            account = account.Trim();
            var model = dao.Get(p => p.Account == account);
            if (model == null)
            {
                return new BoolMessage(false, "账号密码错误");
            }

            //var encryptedPwd = GenerateEncryptPassword(password);
            if (!model.Password.Equals(encryptpassword))
            {
                return new BoolMessage(false, "账号密码错误");
            }

            model.IsLogin = true;
            dao.Update(model, p => p.Account == account, new[] { nameof(UserModel.IsLogin) });
            return BoolMessage.True;
        }

        public BoolMessage Logout(string account)
        {
            var v_result = ValidateAccount(account);
            if (v_result.Failure)
            {
                return v_result;
            }

            account = account.Trim();
            var result = ExistsAccount(account);
            if (result.Success)
            {
                return new BoolMessage(false, "无效的手机号码");
            }

            var model = new UserModel();
            model.IsLogin = false;
            dao.Update(model, p => p.Account == account, new[] { nameof(UserModel.IsLogin) });
            return BoolMessage.True;
        }

        public BoolMessage<UserModel> GetModel(string account)
        {
            var vc_result = ValidateAccount(account);
            if (vc_result.Failure)
            {
                return new BoolMessage<UserModel>(false, vc_result.Message);
            }

            account = account.Trim();
            var model = dao.Get(p => p.Account == account);
            if (model == null)
            {
                return new BoolMessage<UserModel>(false, "无效的手机号码");
            }
            model.Password = null;
            return new BoolMessage<UserModel>(model);
        }

        /// <summary>
        ///  获取用户信息
        /// </summary>
        /// <param name="weiXinOpenId"></param>
        /// <returns></returns>
        public BoolMessage<UserModel> GetModelByOpenId(string weiXinOpenId)
        {
            if (string.IsNullOrEmpty(weiXinOpenId))
            {
                return new BoolMessage<UserModel>(false, "请传入微信OpenId号");
            }

            weiXinOpenId = weiXinOpenId.Trim();
            var model = dao.Get(p => p.WeiXinOperId == weiXinOpenId);
            if (model == null)
            {
                return new BoolMessage<UserModel>(false, "无效的微信OpenId号");
            }
            model.Password = null;
            return new BoolMessage<UserModel>(model);
        }

        /// <summary>
        /// 修改微信OperId
        /// </summary>
        /// <param name="account"></param>
        /// <param name="weiXinOperId"></param>
        public BoolMessage ModifyWeiXinOperId(string account, string weiXinOperId)
        {
            var vc_result = ValidateAccount(account);
            if (vc_result.Failure)
            {
                return vc_result;
            }
            if (string.IsNullOrEmpty(weiXinOperId))
            {
                return new BoolMessage(false, "请输入微信OperId");
            }

            account = account.Trim();
            var result = ExistsAccount(account);
            if (result.Success)
            {
                return new BoolMessage(false, "无效的手机号码");
            }

            var model = new UserModel();
            model.WeiXinOperId = weiXinOperId;
            //检测WeiXinOperId长度
            var v_result = ValidateProperty(model, nameof(UserModel.WeiXinOperId), model.WeiXinOperId);
            if (v_result.Failure)
            {
                return v_result;
            }

            dao.UpdateInclude(model, p => p.Account == account, p => p.WeiXinOperId);
            return BoolMessage.True;
        }

        /// <summary>
        ///  删除微信OperId
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public BoolMessage DelWeiXinOpenId(string account)
        {
            var vc_result = ValidateAccount(account);
            if (vc_result.Failure)
            {
                return vc_result;
            }

            account = account.Trim();
            var result = ExistsAccount(account);
            if (result.Success)
            {
                return new BoolMessage(false, "无效的手机号码");
            }

            var model = new UserModel();
            model.WeiXinOperId = "";

            dao.UpdateInclude(model, p => p.Account == account, p => p.WeiXinOperId);
            return BoolMessage.True;
        }

        /// <summary>
        /// 生成用户加密后密码
        /// </summary>
        /// <param name="password">密码(明文)</param>
        /// <returns>返回加密后的密码</returns>
        private string GenerateEncryptPassword(string password)
        {
            return StringHelper.Md5Encrypt(password);
        }


        private BoolMessage ValidateProperty(object objectInstance, string propertyName,
            object propertyValue)
        {
            var validationResults = new List<ValidationResult>();
            var context = new ValidationContext(objectInstance, null, null);
            context.DisplayName = context.MemberName = propertyName;
            var isValid = Validator.TryValidateProperty(propertyValue, context, validationResults);
            if (!isValid)
            {
                var msg = string.Join("\r\n", validationResults.Select(x => x.ErrorMessage));
                return new BoolMessage(false, msg);
            }
            return BoolMessage.True;
        }

        private BoolMessage ValidateAccount(string account)
        {
            if (string.IsNullOrEmpty(account))
            {
                return new BoolMessage(false, "请输入手机号码");
            }
            return BoolMessage.True;
        }
    }
}